<?php

class OaHscTcpRequest
{
    private $_errno = 0;
    private $_error = '';
    private $_ip;
    private $_port;
    private $_connectTimeout = 2;
    private $_timeout = 5;
    private $_params = array(
        'SERVICE_NAME' => '',    // 服务名，对Open网站来说为M_APP1
        'ret_type' => 'json',    // 返回数据格式
        'key' => 'abc',          // 要查询的库表名称，格式为db.table
        'cmd' => ''	             // 协议号
    );
    
    public function __construct($ip, $port, $serviceName, $params = array(), $logger = null)
    {
        $this->_ip = $ip;
        $this->_port = $port;
        $params['SERVICE_NAME'] = $serviceName;
        $this->_params = array_merge($this->_params, $params);
        if (is_null($logger)) {
            $this->_logger = Log::factory('null');
        } else {
            $this->_logger = $logger;
        }
    }
    
    public function _setError($errno, $error = '')
    {
        $this->_errno = $errno;
        $this->_error = $error;
        return true;
    }
    
    public function getErrorNo()
    {
        return $this->_errno;
    }
    
    public function getErrorMessage()
    {
        return $this->_error;
    }
    
    public function setServiceName($serviceName)
    {
        $this->_params['SERVICE_NAME'] = $serviceName;
        return true;
    }
    
    public function setRetType($retType)
    {
        $this->_params['ret_type'] = $retType;
        return true;
    }
    
    public function setKey($key)
    {
        $this->_params['key'] = $key;
        return true;
    }
    
    public function setCmd($cmd)
    {
        $this->_params['cmd'] = $cmd;
        return true;
    }
    
    public function setConnectTimeout($timeout)
    {
        return $this->_connectTimeout = $timeout;
    }
    
    public function setTimeout($timeout)
    {
        return $this->_timeout = $timeout;
    }
    
    public function send($params = array())
    {
        $params = array_merge($this->_params, $params);
        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if (!socket_connect($socket, $this->_ip, $this->_port)) {
            $errno = socket_last_error($socket);
            $error = socket_strerror($errno);
            $this->_setError($errno, $error);
            return false;
        }
        $msg = msgpack_pack($params);
        $len = strlen($msg);
        if (socket_send($socket, $msg, $len) != $len) {
            $errno = socket_last_error($socket);
            $error = socket_strerror($errno);
            $this->_setError($errno, $error);
            return false;
        }
        if (socket_recv($socket, $result) === false) {
            $errno = socket_last_error($socket);
            $error = socket_strerror($errno);
            $this->_setError($errno, $error);
            return false;
        }
        $result = msgpack_unpack($result);
        return $result;
    }
    
    /**
     * 透传SQL协议，中间层直接把SQL递交给数据库
     * @param string $sql
     * @return array|boolean
     */
    public function sendSql($sql)
    {
        return $this->send(array(
            'cmd' => 'M1',
            'sql' => $sql
        ));
    }
}